#include <cstdio>
#include <vector>
#include <climits>

using namespace std;

struct edge_info {
    int next;
    int distance;
    int cost;
};

vector<edge_info> edge[1001];
bool union_mark[1001]; //mark[j] = true means node j has been in union
int dis_vector[1001];
int cost_info[1001];

int main(int argc, char const *argv[]) {
    int n, m;
    int start, end;
    while (scanf("%d%d", &n, &m) != EOF) {
        if (n == 0 && m == 0)
            break;
        for (int i = 1; i <= n; ++i)
            edge[i].clear();
        for (int i = 0; i < m; ++i) {
            int a, b, distance, cost;
            scanf("%d%d%d%d", &a, &b, &distance, &cost);
            edge_info temp_edge;
            temp_edge.distance = distance;
            temp_edge.cost = cost;
            temp_edge.next = b;
            edge[a].push_back(temp_edge);
            temp_edge.next = a;
            edge[b].push_back(temp_edge);
        }
        scanf("%d%d", &start, &end);
        //initial
        for (int i = 1; i <= n; ++i) {
            dis_vector[i] = -1; //unreachable
            union_mark[i] = false;
        }
        dis_vector[start] = 0; //check start node's shortest path
        union_mark[start] = true;
        int new_node = start;
        for (int i = 1; i < n; ++i) { //loop n-1 times
            for (int j = 0; j < edge[new_node].size(); ++j) {
                int next_node = edge[new_node][j].next;
                int edge_cost = edge[new_node][j].cost;
                int edge_distance = edge[new_node][j].distance;
                if (union_mark[next_node])
                    continue;
                if (dis_vector[next_node] == -1 || dis_vector[next_node] > dis_vector[new_node] + edge_distance ||
                    dis_vector[next_node] == dis_vector[new_node] + edge_distance &&
                    cost_info[next_node] > cost_info[new_node] + edge_cost) {
                    dis_vector[next_node] = dis_vector[new_node] + edge_distance;
                    cost_info[next_node] = cost_info[new_node] + edge_cost;
                }
            }
            int min_num = INT_MAX; //select next new_node
            for (int j = 1; j <= n; j++) {
                if (union_mark[j])
                    continue;
                if (dis_vector[j] == -1)
                    continue;
                if (dis_vector[j] < min_num) {
                    min_num = dis_vector[j];
                    new_node = j;
                }
            }
            union_mark[new_node] = true;
        }
        printf("%d %d\n", dis_vector[end], cost_info[end]);
    }
    return 0;
}

